home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-19 | 56.6 KB | 1,662 lines | [TEXT/KAHL] |
- // I included some of my own drawing definitions. Might want to check them out to understand them.
- // I know that my intent was to make this as simple as possible, but for me this is simple. Nothing
- // to complicated. Just some standard color definitions. Look at "MyColors.c" to see the functions.
-
- // include files
- #if !defined(powerc) && !defined (__powerc)
- #include <SetUpA4.h>
- #endif
-
- // Prototypes
- static pascal long MyControl( short variation, ControlHandle theControl, short message, long param );
- void SetUpMyControl( CntlParam theParam );
- void DrawMyControl( ControlHandle theControl, short part );
- short TestMyControlParts( ControlHandle theControl, Point clickPnt );
- void InitMyControl( ControlHandle theControl );
- void DisposeMyControl( ControlHandle theControl );
- void FillCntlParameters( ControlHandle theControl, CntlParmPtr *param );
- void CalcMyThumbPosition( ControlHandle theControl, Rect *realThumbRect );
- void DrawMyArrow( short var, Rect theRect );
- void DragMyThumb( ControlHandle theControl, Point mousePnt );
- void DragMyControl( ControlHandle theControl, Point mousePnt );
- void DrawMyThumb( ControlHandle theControl, Boolean var );
- void CalcMyThumbRgn( ControlHandle theControl, RgnHandle *param );
- void PositionMyCntl( ControlHandle theControl, Point mousePnt );
- void ConvertPtToVal( ControlHandle theControl, Point newPoint, short *value );
- void DrawValueInThumb( ControlHandle theControl, long value );
-
- // Globals
- extern Main myMain; // declared in Window-Main.c
-
- // Macros & defines
- #define MY_THUMB_LENGTH 32 // simply put, this is the length of our thumb indicator.
-
- /******************************************************************************
-
- Your code resource function starts here.
-
- variation - If you have varitions of this control and they were implemented
- in you code, then if the user specifies one you will recieve it here.
- Example: Code Resource ID * 16 + varition
-
- theControl - a handle leading to the control record.
-
- msg - this will be a message from the application to tell you what it
- wants. It could be drawCntl, testCntl, etc.
-
- param - this is a 4-byte value that is dependent on the msg.
- Examples of some are below in the msg's.
-
- *******************************************************************************/
- static pascal long MyControl( short variation, ControlHandle theControl, short msg, long param )
- {
- Point mousePnt;
- Boolean test;
-
-
- #if !defined(powerc) && !defined (__powerc) // Don't bother setting up registers if PowerPC
- SetUpA4();
- #endif
-
- HLock( (Handle)theControl );
- if( (**theControl).contrlData ) {
-
- HLock( (**theControl).contrlData );
-
- }
-
- // Use 'msg' to determine what the application is wanting our control to do.
-
- switch( msg )
- {
- //------------------------------------------------------------------------
- //
- // drawCntl ( message = 0 ) IM:Macintosh ToolBox Essentials : Page 5-111
- //
- // Draw the entire control or draw the part specified by LoWord( param ).
- // Be sure to check the control's hilite value. If your control has an
- // indicator or thumb and param = 129 you must erase the thumb from it's
- // current position and redraw it according to the control's new value.
- // Do not draw anything if the control is invisible.
- //
- // Return - A zero. (always)
- //------------------------------------------------------------------------
- case drawCntl:
- if( (**theControl).contrlVis == 255 ) {
- DrawMyControl( theControl, LoWord( param ) );
- }
- return( 0L );
- break;
-
- //------------------------------------------------------------------------
- //
- // testCntl ( message = 1 ) IM:Macintosh ToolBox Essentials : Page 5-112
- //
- // Check to see if the mouse point is in the control's rect or not.
- // horizontal = LoWord( param )
- // vertical = HiWord( param )
- // This would be the area you create your parts if you have multiple things on
- // your control. Like a thumb, arrows, pageUp, etc..
- //
- // Return - The part code of the part that contains the mouse point.
- // Return zero if the mouse point is outside the part or
- // the control is inactive.
- //------------------------------------------------------------------------
- case testCntl:
- // first extract the mouse position
- mousePnt.h = LoWord( param );
- mousePnt.v = HiWord( param );
-
- // now determine if the mouse click was within our cntl rect.
- if( PtInRect( mousePnt, &(**theControl).contrlRect )) {
-
- // the click was inside our control so now define what part it was in.
- return( TestMyControlParts( theControl, mousePnt ));
-
- } else {
-
- // the click wasn't within our control. Don't do anything.
- return( 0L );
-
- }
- break;
-
- //------------------------------------------------------------------------
- //
- // calcCRgns ( message = 2 ) IM:Macintosh ToolBox Essentials : Page 5-112
- //
- // For non System 7.x systems. The low 3 bytes of param is a region handle.
- // ( 4 bytes for 32-bit systems ). Mask the high byte and update the region
- // to enclose the entire control. If the high bit is set then it's asking for
- // the thumb or indicator. If not just use the entire control.
- //
- // Return - A zero. (always) Be sure to express the region in local coordinates.
- //------------------------------------------------------------------------
- case calcCRgns:
- if(( param & 0x80000000 ) == 0 ) {
-
- // calculate the entire control.
- RectRgn( (RgnHandle)(param & 0x00FFFFFF), &(**theControl).contrlRect );
-
- } else {
-
- // calculate only the indicator.
- Rect realThumbRect;
-
- // obtain the current thumb position
- CalcMyThumbPosition( theControl, &realThumbRect );
- RectRgn( (RgnHandle)(param & 0x00FFFFFF), &realThumbRect );
- }
- return( 0L );
- break;
-
- //------------------------------------------------------------------------
- //
- // initCntl ( message = 3 ) IM:Macintosh ToolBox Essentials : Page 5-113
- //
- // Do any special inititailization, calculations or allocations here. For a
- // standard scroll bar you would normally allocate the space for a region to
- // the control's rect and region handles for the parts and store them in the
- // 'contrlData' field in the control's record.
- //
- // Return - A zero. (always)
- //------------------------------------------------------------------------
- case initCntl:
- InitMyControl( theControl );
- return( 0L );
- break;
-
- //------------------------------------------------------------------------
- //
- // dispCntl ( message = 4 ) IM:Macintosh ToolBox Essentials : Page 5-113
- //
- // Do any special disposal of your control here.
- //
- // Return - A zero. (always)
- //------------------------------------------------------------------------
- case dispCntl:
- DisposeMyControl( theControl );
- return( 0L );
- break;
-
- //------------------------------------------------------------------------
- //
- // posCntl ( message = 5 ) IM:Macintosh ToolBox Essentials : Page 5-113
- //
- // Redraw the thumb and update the control's value.
- // You use this wether you use default dragging or not.
- // horizontal = LoWord( param ) = horizontal offset in pixels to move your indicator
- // vertical = HiWord( param ) = vertical offset in pixels to move your indicator
- //
- // Return - A zero. (always)
- //------------------------------------------------------------------------
- case posCntl:
- // if you would like to test custom dragging comment out this function and
- // un-comment the functions in 'dragCntl'. Leave return( 0L ) the same.
-
- mousePnt.h = LoWord( param );
- mousePnt.v = HiWord( param );
- PositionMyCntl( theControl, mousePnt );
-
- return( 0L );
- break;
-
- //------------------------------------------------------------------------
- //
- // thumbCntl ( message = 6 ) IM:Macintosh ToolBox Essentials : Page 5-114
- //
- // When you recieve this message param points to a struct which you should
- // fill with thumb motion constraints.
- //
- // struct {
- // Rect limitRect; // on entry, top-left is the mouse point (local coord)
- // // on exit this should be the same as the track rects
- // // coordinates. ( take in account the thumb width )
- // Rect slopRect; // if the user drags outiside this rect
- // // the control will stop dragging.
- // short axis; // The axis constraints the user may drag the control.
- // // constants than can be used are:
- // // noConstraint = 0; ( no constraint )
- // // hAxisOnly = 1; ( drag horizontal only )
- // // vAxisOnly = 2; ( drag vertical only )
- //
- // * these values are ignored if you use any custom dragging
- //
- // Return - Just fill in the struct.
- //------------------------------------------------------------------------
- case thumbCntl:
- FillCntlParameters( theControl, (CntlParmPtr*)¶m );
- break;
-
- //------------------------------------------------------------------------
- //
- // dragCntl ( message = 7 ) IM:Macintosh ToolBox Essentials : Page 5-114
- //
- // If param = 0 then drag the entire control. If param = non-zero then
- // just drag the indicator or thumb. For default dragging just return
- // a 0 (zero). For custom dragging, follow the mouse around untill released
- // then handle the details and return a non-zero.
- // NOTE: If you do return a zero then you can ignore postCntl and thumbCntl.
- //
- // Return - For default dragging, return a zero. If your return something else
- // then the control manager does not drag your control. But instead
- // relies on your custom drag procedure.
- //------------------------------------------------------------------------
- case dragCntl:
- // if you would like to test these functions (custom dragging) remove
- // the comments and comment out the functions in 'posCntl'
-
- //GetMouse( &mousePnt );
- //DragMyThumb( theControl, param, mousePnt );
- //return( 1 );
-
- return( 0L ); // comment out for custom dragging.
- break;
-
- //------------------------------------------------------------------------
- //
- // autoTrack ( message = 8 ) IM:Macintosh ToolBox Essentials : Page 5-115
- //
- // This message will be sent if you specify -1 in the final parameter of
- // TrackControl() and the contrlAction of the control is also -1. If so,
- // LoWord( param ) will contain a part code and a handle to a routine
- // to take care of it. Basically an action procedure as set by the user.
- //------------------------------------------------------------------------
- case autoTrack:
- break;
-
- // The folowing messages are used only if the user is running System 7.x
- // and when 32-bit addressing is enabled.
-
- //------------------------------------------------------------------------
- //
- // calcCntlRgn ( message = 10 ) IM:Macintosh ToolBox Essentials : Page 5-111
- //
- // This is essentially the same as calcCRgns except you do not have to
- // mask out the high byte of the region handle. Used only when 32-bit
- // addressing is on and running system 7.x. If running 24-bit addressing
- // calcCRgns will still be used.
- //
- // Return - A zero (always) Be sure to express the region in local coordinates.
- //------------------------------------------------------------------------
- case calcCntlRgn:
- RectRgn( (RgnHandle)param, &(**theControl).contrlRect );
- return( 0L );
- break;
-
- //------------------------------------------------------------------------
- //
- // calcThumbRgn ( message = 11 ) IM:Macintosh ToolBox Essentials : Page 5-111
- //
- // This is asking you to calculate your indicator or thumb's region. Used
- // only when 32-bit adressing is on and running system 7.x. If running
- // 24-bit addressing calcCRgns will still be used.
- //
- // Return - A zero (always) Be sure to express the region in local coordinates.
- //------------------------------------------------------------------------
- case calcThumbRgn:
- CalcMyThumbRgn( theControl, (RgnHandle*)¶m );
- return( 0L );
- break;
- }
-
- HUnlock( (Handle)theControl );
- if( (**theControl).contrlData ) {
-
- HUnlock( (**theControl).contrlData );
-
- }
-
- #if !defined(powerc) && !defined (__powerc) // Don't bother setting up registers if PowerPC
- RestoreA4();
- #endif
-
- }
-
- /******************************************************************************
-
- This procedure will setup you control when you are ready to allocate it.
- It needs to be placed with the code up above (static pascal long MyControl)
-
- *******************************************************************************/
- void SetUpMyControl( CntlParam theParam )
- {
- // store the CDEF UPP in the refCon of the control, the CDEF stub gets
- // the address in the refCon and calls that UPP for CDEF messages
-
- myMain.hControl = NewControl( theParam.theWindow,
- &theParam.cntlRect,
- theParam.title,
- theParam.visible,
- theParam.initialValue,
- theParam.min,
- theParam.max,
- theParam.cntlType,
- (long)NewControlDefProc( MyControl ) );
- }
-
- /******************************************************************************
-
- Draw the control. Check to see if it's active and if so, what part to draw.
- Also you need to check to see if the control is horizontal or vertical and
- can we draw in color.
-
- *******************************************************************************/
- void DrawMyControl( ControlHandle theControl, short part )
- {
- Rect cntlRect, thumbRect, arrowLT, arrowRB, trackRect;
- short cntlHilite, vCenter, hCenter;
- RgnHandle arrow;
- RGBColor theColor;
- Point mousePnt;
- MyCntlDataHan myData;
-
- // retrieve the part information from the control's data field.
- myData = (MyCntlDataHan)(**theControl).contrlData;
-
- // Did we retrieve the data?
- if( myData != nil ) {
-
- // It worked, Alrighty then...
-
- // set up some variables
- cntlRect = (**theControl).contrlRect;
- cntlHilite = (**theControl).contrlHilite;
- thumbRect = (**myData).thumbRect;
- arrowLT = (**myData).arrowLT;
- arrowRB = (**myData).arrowRB;
- trackRect = (**myData).trackRect;
-
- // determine the centers for drawing. I haven't checked to see if I'm
- // drawing a vertical or horizontal control. You will need to do this.
- vCenter = ( cntlRect.bottom - cntlRect.top ) / 2;
- hCenter = ( cntlRect.right - cntlRect.left ) / 2;
-
-
- // Determine what the hilite state of the control is
- if( cntlHilite == 255 )
- {
- // the control is inactive. Draw accordingly
- SetForeColor( GREY_C );
- FrameRect( &cntlRect );
- FrameRect( &arrowLT );
- FrameRect( &arrowRB );
- CalcMyThumbPosition( theControl, &thumbRect );
- FrameRect( &thumbRect );
- ColorNormal();
-
- } else {
-
- // ok, so the control is active. now what part should we draw
- switch( part )
- {
- //draw the entire control
- case 0:
- // ok first thing's first, let's erase the control. I'm checking to see
- // what the control's owner's (window) content color is. Just to be nice.
- GetWinBackColor( (**theControl).contrlOwner, &theColor );
- RGBBackColor( &theColor );
- EraseRect( &cntlRect );
-
- //------------------------------------------------
- // Draw left arrow
- //
- SetForeColor( GREY_B );
- PaintRect( &arrowLT );
- //--- add hilites and shadows
- HiliteAndShadow( WHITE_COLOR, GREY_E, 0, arrowLT );
- FrameRect( &arrowLT );
- //--- add the black arrows. check to see if we are horz or vert
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we are horizontal
- DrawMyArrow( 0, arrowLT );
-
- } else {
-
- // we are vertical
- DrawMyArrow( 1, arrowLT );
-
- }
-
- //------------------------------------------------
- // Draw right arrow
- //
- SetForeColor( GREY_B );
- PaintRect( &arrowRB );
- //--- add hilites and shadows
- HiliteAndShadow( WHITE_COLOR, GREY_E, 0, arrowRB );
- FrameRect( &arrowRB );
- //--- add the black arrows. check to see if we are horz or vert
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we are horizontal
- DrawMyArrow( 2, arrowRB );
-
- } else {
-
- // we are vertical
- DrawMyArrow( 3, arrowRB );
-
- }
-
-
- //------------------------------------------------
- // Draw the track part and the thumb. We put these
- // together because we might have to erase an old thumb position.
- //
- DrawMyThumb( theControl, 0 );
- break;
-
-
-
- case 20: // inUpButton
- //------------------------------------------------
- // Let's erase the arrow's rect. Agin I'm getting the content color
- // of the controls owner. (the window we're in)
- //
- GetWinBackColor( (**theControl).contrlOwner, &theColor );
- RGBBackColor( &theColor );
- EraseRect( &arrowLT );
-
- GetMouse( &mousePnt );
- if( PtInRect( mousePnt, &arrowLT ) && Button()) {
-
- //------------------------------------------------
- // Draw left arrow - inverted
- //
- SetForeColor( GREY_E );
- PaintRect( &arrowLT );
- //--- add hilites and shadows
- HiliteAndShadow( GREY_H, GREY_B, 0, arrowLT );
- FrameRect( &arrowLT );
- //--- add the arrows. check to see if we are horz or vert
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we are horizontal
- DrawMyArrow( 0, arrowLT );
-
- } else {
-
- // we are vertical
- DrawMyArrow( 1, arrowLT );
-
- }
-
- } else {
-
- //------------------------------------------------
- // Draw left arrow - normal
- //
- SetForeColor( GREY_B );
- PaintRect( &arrowLT );
- //--- add hilites and shadows
- HiliteAndShadow( WHITE_COLOR, GREY_E, 0, arrowLT );
- FrameRect( &arrowLT );
- //--- add the arrows. check to see if we are horz or vert
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we are horizontal
- DrawMyArrow( 0, arrowLT );
-
- } else {
-
- // we are vertical
- DrawMyArrow( 1, arrowLT );
-
- }
-
- }
- ColorNormal();
- break;
-
-
-
-
- case 21: //inDownButton
- //------------------------------------------------
- // Let's erase the arrow's rect. Again I'm getting the content color
- // of the controls owner. (the window we're in)
- //
- GetWinBackColor( (**theControl).contrlOwner, &theColor );
- RGBBackColor( &theColor );
- EraseRect( &arrowRB );
-
- //________________________________________________
- // We need to determine how we should draw the arrows. Is the user
- // clicking on them or is it normal? If it is being clicked on then
- // we should check where the mouse is and if the button is down. This
- // will determine if we draw the control inverted or not.
- //
- GetMouse( &mousePnt );
- if( PtInRect( mousePnt, &arrowRB ) && Button()) {
-
- //------------------------------------------------
- // Draw right arrow - inverted
- //
- SetForeColor( GREY_E );
- PaintRect( &arrowRB );
- //--- add hilites and shadows
- HiliteAndShadow( GREY_H, GREY_B, 0, arrowRB );
- FrameRect( &arrowRB );
- //--- add the black arrows. check to see if we are horz or vert
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we are horizontal
- DrawMyArrow( 2, arrowRB );
-
- } else {
-
- // we are vertical
- DrawMyArrow( 3, arrowRB );
-
- }
-
- } else {
-
- //------------------------------------------------
- // Draw right arrow - normal
- //
- SetForeColor( GREY_B );
- PaintRect( &arrowRB );
- //--- add hilites and shadows
- HiliteAndShadow( WHITE_COLOR, GREY_E, 0, arrowRB );
- FrameRect( &arrowRB );
- //--- add the black arrows. check to see if we are horz or vert
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we are horizontal
- DrawMyArrow( 2, arrowRB );
-
- } else {
-
- // we are vertical
- DrawMyArrow( 3, arrowRB );
-
- }
-
- }
- ColorNormal();
- break;
-
-
-
- case 22: // inPageUp
- case 23: // inPageDown
- //------------------------------------------------
- // All we need to do here is determine if we are to the left or right
- // ( or top or bottom ) of the thumb's position. Then create a rect
- // who's left or right ( top or bottom ) is that of the thumb's.
- //
-
- // get the current mouse position
- GetMouse( &mousePnt );
-
- // need to find if we are a vert or horz control. Only need to do this when
- // we are inverting the control. We need to draw the entire control when
- // asked to draw it normally. Why?!? Because when we invert it we create
- // Hilites and shadows which need to be erased.
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we are horizontal
-
- // find out where our current thumb is located ( real corrdinates )
- CalcMyThumbPosition( theControl, &thumbRect );
-
- // where is the mouse? on the right or the left?
- if( mousePnt.h <= thumbRect.left ) {
- trackRect.right = thumbRect.left;
- } else {
- trackRect.left = thumbRect.right - 1;
- }
-
- } else {
-
- // we are a vertical control
-
- // find out where our current thumb is located ( real corrdinates )
- CalcMyThumbPosition( theControl, &thumbRect );
-
- // where is the mouse? on the top or the bottom?
- if( mousePnt.v <= thumbRect.top ) {
- trackRect.bottom = thumbRect.top + 1;
- } else {
- trackRect.top = thumbRect.bottom - 1;
- }
- }
-
- // now figure out how to draw it. ( inverted or normal )
- // and check to see if the are in the track portion or not.
- if( PtInRect( mousePnt, &trackRect ) && Button()) {
-
- //------------------------------------------------
- // Draw the trackRect part ( not the thumb ) - inverted
- //
- InvertRect( &trackRect );
- SetForeColor( GREY_C );
- PaintRect( &trackRect );
- //--- add hilites and shadows
- HiliteAndShadow( GREY_G, WHITE_COLOR, 0, trackRect );
- FrameRect( &trackRect );
-
- } else {
-
- //------------------------------------------------
- // Draw the track part ( not the thumb ) - normal
- //
- SetForeColor( GREY_A );
- PaintRect( &trackRect );
- //--- add hilites and shadows
- HiliteAndShadow( GREY_C, WHITE_COLOR, 0, trackRect );
- FrameRect( &trackRect );
-
- CalcMyThumbPosition( theControl, &thumbRect );
- SetForeColor( GREY_B );
- PaintRect( &thumbRect );
- //--- add hilites and shadows
- HiliteAndShadow( WHITE_COLOR, GREY_E, 0, thumbRect );
- FrameRect( &thumbRect );
-
- }
- break;
-
-
- case 129: // inThumb
- // We don't have to do this here. Actually i don't believe it
- // will even get called here. This has it's own routine I believe.
- break;
-
- }
-
- }
- } else {
-
- // we had some problem retrieving our data
- ReportError( "\pCouldn't retrieve data for drawing the control." );
-
- }
- }
-
- /******************************************************************************
-
- Test to see what part the user clicked in. We already checked to see if the
- mouse click was actually inside the control. It was, so now see what part
- they clicked in and return a number for it. Apple has a set of variables that
- is uses for standard controls. So since our control is a variation of a normal
- slider we'll use their variables. Check out FindControl() in IM or THINK Ref.
-
- *******************************************************************************/
- short TestMyControlParts( ControlHandle theControl, Point clickPnt )
- {
- Rect pageLeft, pageRight, realThumbRect, cntlRect;
- MyCntlDataHan myData;
-
- // For our own refrence let's define our parts..
- //
- // thumb = inThumb = 129
- // arrowLT = inUpButton = 20
- // arrowRB = inDownButton = 21
- // pageLeft = inPageUp = 22
- // pageRight = inPageDown = 23
-
- // ok let's get our stored data from the control's contrlData field
- myData = (MyCntlDataHan)(**theControl).contrlData; // force the data to form to our struct
-
- // set up the control's rectangle for testing
- cntlRect = (**theControl).contrlRect;
-
- // we need to find out what the real thhumb on the control's rect is
- CalcMyThumbPosition( theControl, &realThumbRect );
-
- // double check to make sure that in fact we have data to play with
- if( myData != nil ) {
-
- // it worked. wow!
- // now, all we do is test where exactly in the control the click was.
-
- //is it in the thumb?
- if( PtInRect( clickPnt, &realThumbRect ) ) {
- return( inThumb );
- } else {
-
- // is it in one of the arrows?
- if( PtInRect( clickPnt, &(**myData).arrowLT ) ) {
- return( inUpButton );
- } else {
-
- if( PtInRect( clickPnt, &(**myData).arrowRB ) ) {
- return( inDownButton );
- } else {
-
- // is it in the trackRect somewhere?
- if( PtInRect( clickPnt, &(**myData).trackRect ) ) {
-
- // we have to see if it's to the right of the thumb or left of it. Or if we are
- // a vertical control the top and the bottom.
-
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we have a horizontal control
-
- pageLeft = pageRight = (**myData).trackRect;
- pageLeft.right = realThumbRect.left;
- pageRight.left = realThumbRect.right;
-
- } else {
-
- // we have a vertical control
-
- pageLeft = pageRight = (**myData).trackRect;
- pageLeft.bottom = realThumbRect.top;
- pageRight.top = realThumbRect.bottom;
-
- }
-
- if( PtInRect( clickPnt, &pageLeft ) ) {
- return( inPageUp );
- } else {
- if( PtInRect( clickPnt, &pageRight ) ) {
- return( inPageDown );
- }
- }
-
- } else {
-
- // hey it wasn't in any of my rects. how'd that happ'n?
- ReportError( "\pTesting points and couldn't find point within any of my parts." );
- }
- }
- }
- }
-
- } else {
-
- // retrieving the control's data failed.
- ReportError( "\pCouldn't retrieve control data while testing the control." );
-
- }
-
- }
-
- /******************************************************************************
-
- When we recieve a 'initCntl' message in our control we use this procedure
- to set up the 'contrlData' field in our control. This data is used to
- store information about our control that we will use throughout it's life.
-
- *******************************************************************************/
- void InitMyControl( ControlHandle theControl )
- {
- Rect cntlRect, thumbRect, arrowLT, arrowRB, trackRect, slopRect;
- short cntl_high = 0, cntl_wide = 0;
- MyCntlDataHan myData;
-
- // set our cntlRect to equal the control's rect.
- cntlRect = (**theControl).contrlRect;
-
- // we need to determine if we have a vertical or horizontal control
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we have a horizontal control
-
- // the first thing to do is determine the height of our control to make square arrows buttons
- cntl_high = cntlRect.bottom - cntlRect.top;
-
- // first we'll set the arrow buttons.
- SetRect( &arrowLT, cntlRect.left, cntlRect.top, cntlRect.left + cntl_high, cntlRect.bottom );
- SetRect( &arrowRB, cntlRect.right - cntl_high, cntlRect.top, cntlRect.right, cntlRect.bottom );
-
- // Now we'll set the track's rectangle. Take the cntlRect - the arrow buttons.
- trackRect = cntlRect;
- trackRect.left = arrowLT.right - 1; // we want them to overlap.
- trackRect.right = arrowRB.left + 1; // we want them to overlap.
-
- // Now we'll set the thumb rect up. We don't have to actually set the rect
- // to it's exact position, but just the size for now.
- // Right = width
- // Bottom = height (cntlRect's height - 2, so it's inset little.)
- SetRect( &thumbRect, 0, 0, MY_THUMB_LENGTH, cntl_high - 2 );
-
- } else {
-
- // we have a vertical control
-
- // the first thing to do is determine the width of our control to make square arrows buttons
- cntl_wide = cntlRect.right - cntlRect.left;
-
- // first we'll set the arrow buttons.
- SetRect( &arrowLT, cntlRect.left, cntlRect.top, cntlRect.right, cntlRect.top + cntl_wide );
- SetRect( &arrowRB, cntlRect.left, cntlRect.bottom - cntl_wide, cntlRect.right, cntlRect.bottom );
-
- // Now we'll set the track's rectangle. Take the cntlRect - the arrow buttons.
- trackRect = cntlRect;
- trackRect.top = arrowLT.bottom - 1;
- trackRect.bottom = arrowRB.top + 1;
-
- // Now we'll set the thumb rect up. We don't have to actually set the rect
- // to it's exact position, but just the size for now.
- // Right = height (cntlRect's height - 2, so it's inset little.)
- // Bottom = width
- SetRect( &thumbRect, 0, 0, cntl_wide - 2, MY_THUMB_LENGTH );
- }
-
- // we need to set the size of the handle we are using
- myData = (MyCntlDataHan)NewHandle( sizeof( MyCntlData ) );
-
- if( myData != nil ) {
-
- // now store our handle in the contrlData field in the control record
- (**theControl).contrlData = (Handle)myData;
-
- // now simply copy this information into our handle.
- (**myData).cntlRect = cntlRect;
- (**myData).thumbRect = thumbRect;
- (**myData).arrowLT = arrowLT; // left or top arrow
- (**myData).arrowRB = arrowRB; // right or bottom arrow
- (**myData).trackRect = trackRect;
-
- } else {
-
- // We had any error. Respond what error had occured.
- ReportError( "\pCouldn't allocate area for the data handle." );
-
- }
-
- }
-
- /******************************************************************************
-
- This procedure will get called when we recieve a 'dispCntl' in the
- param of our control. All we need to do is distroy any data that we
- initialized earlier in the 'initCntl' procedure.
-
- *******************************************************************************/
- void DisposeMyControl( ControlHandle theControl )
- {
- MyCntlDataHan myData;
-
- if( theControl != nil ) {
-
- // Get the handle to the control's data.
- myData = (MyCntlDataHan)(**theControl).contrlData;
-
- if( myData != nil ) {
-
- // lock the structs data.
- HLock( (Handle) myData );
-
- // dispose of our data handle and set the contrlData field to nil.
- DisposeHandle( (Handle) myData );
- (**theControl).contrlData = nil;
-
- } else {
-
- // error occurred trying to retreive info from the control's data field.
- ReportError( "\pCouldn't retrieve control data information." );
-
- }
- } else {
-
- // For some reason we didn't get a true control handle passed to us
- ReportError( "\pTried to extract data information, but was passed a bad control handle." );
-
- }
- }
-
- /******************************************************************************
-
- Out Control recieved a 'thumbCntl' message. We need to fill in the parameters
- of the controls limit rect and slop rect and axis.
-
- By the way, CntlParm is a struct defined on top. We use it here to set up
- or force the data that lies within 'param' to match our requirements.
-
- *******************************************************************************/
- void FillCntlParameters( ControlHandle theControl, CntlParmPtr *param )
- {
- Rect limitRect, slopRect, cntlRect, realThumbRect;
- short axis;
- Point mousePnt;
- MyCntlDataHan myData;
-
- // You may be asking yourself, "What exactly are we doing here?"
- // Well we are setting some parameters, that Apple has provided
- // us control definition makers, to allow some helpful human
- // interaction. ( At least I think so ).
- //
- // The limitRect gives us the mouse coordinates on entry. On exit
- // this rect should contain the control track rectangle. The slopRect
- // gives us an area in which the user can drag outside the control's
- // rectangle in which the control will still respond. If the user moves
- // outside this 'slop rectangle' then the control will return to it's
- // previous state. The axis constrain the drag movement depending on the
- // setting. noContraint = 0 ( no constraint ), hAxisOnly = 1 ( horizontal only ),
- // vAxisOnly = 2 ( vertical only ).
-
- // extract data from the contrlData field and form to our struct.
- myData = (MyCntlDataHan)(**theControl).contrlData;
-
- // let's get the true or real thumb rect ( the one that gets drawn )
- CalcMyThumbPosition( theControl, &realThumbRect );
-
- // set the cntlRect to match the control's rectangle
- cntlRect = (**theControl).contrlRect;
-
- // extract the mouse down points from param
- mousePnt.h = (**param).limitRect.left;
- mousePnt.v = (**param).limitRect.top;
-
- if( myData != nil ) {
-
- // now let's determine if we are using a horz or vert control
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we have ourselves a horizontal control
-
- // adjust the limitRect to take in account where the user clicked within the thumb
- (**param).limitRect.left = (**myData).arrowLT.right + ( mousePnt.h - realThumbRect.left );
- (**param).limitRect.right = (**myData).arrowRB.left - ( (realThumbRect.right-1) - mousePnt.h );
-
- // now let's adjust the slopRect slightly, increase it by 20 pixels...
- (**param).slopRect = (**myData).trackRect;
- InsetRect( &(**param).slopRect, -20, -20 );
-
- // then extend it's edges about 100 pixels. This normally gives the correct feel.
- (**param).slopRect.left -= 100;
- (**param).slopRect.right += 100;
-
- // set up the axis for a horizontal control
- (**param).axis = hAxisOnly;
-
- } else {
-
- // we have a vertical control.
-
- // adjust the limitRect to take in account where the user clicked within the thumb
- (**param).limitRect.top = (**myData).arrowLT.bottom + ( mousePnt.v - realThumbRect.top );
- (**param).limitRect.bottom = (**myData).arrowRB.top - ( (realThumbRect.bottom-1) - mousePnt.v );
-
- // now let's adjust the slopRect slightly, increase it by 20 pixels...
- (**param).slopRect = (**myData).trackRect;
- InsetRect( &(**param).slopRect, -20, -20 );
-
- // then extend it's edges about 100 pixels. This normally gives the correct feel.
- slopRect.top -= 100;
- slopRect.bottom += 100;
-
- // set up the axis for the control
- (**param).axis = vAxisOnly;
-
- }
-
- } else {
-
- // we had an error retreiving data form the control
- ReportError( "\pWe couldn't extract data from the control while calculating the parameters." );
-
- }
- }
-
- /******************************************************************************
-
- This is a fairly straight forward procedure. All we have to do is find the position of
- the thumb on the track and return a rect to match these values. Easy shmeazy. All
- we are doing here is calculating the "Real Thumb Rect" for drawing.
-
- *******************************************************************************/
- void CalcMyThumbPosition( ControlHandle theControl, Rect *realThumbRect )
- {
- long min, max, value, dist;
- short cntl_high, cntl_wide;
- Rect cntlRect, trackRect;
- MyCntlDataHan myData;
-
- // Do some initial setting up
- cntlRect = (**theControl).contrlRect;
- min = (**theControl).contrlMin;
- max = (**theControl).contrlMax;
- value = (**theControl).contrlValue;
- myData = (MyCntlDataHan)(**theControl).contrlData; // force the data to form to our struct
-
- // double check to make sure that in fact we have data to play with
- if( myData != nil ) {
-
- // it worked! cool...
-
- // make sure the value isn't greater or less than max & min
- if( value > max ) {
- value = max;
- } else {
- if( value < min ) {
- value = min;
- }
- }
-
- // retrieve the track rect from our data
- trackRect = (**myData).trackRect;
-
- // Do we have a horizontal or vertical control???
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top )
- {
- // We have horizontal control
-
- // We need to set the trackRect to take in account of the thumb width.
- // We do this so we don't overwrite part of the arrow when we are drawing.
- trackRect.left += ( MY_THUMB_LENGTH / 2 ) + 1;
- trackRect.right -= ( MY_THUMB_LENGTH / 2 ) + 1;
-
- // determine how wide our track rect is and then calculate the distance we move.
- cntl_wide = trackRect.right - trackRect.left;
- dist = trackRect.left + (((max + value) * cntl_wide) / (max - min)) - ( MY_THUMB_LENGTH / 2 );
-
- // we know that the top and bottom of our thumb rect will be the same as the
- // control's rect (basically). It's actually inset 1 pixel to fit inside the track.
- (*realThumbRect).top = cntlRect.top + 1;
- (*realThumbRect).bottom = cntlRect.bottom - 1;
-
- // now set the left and right to the correct coordinates for drawing.
- (*realThumbRect).left = (**myData).thumbRect.left + dist;
- (*realThumbRect).right = (**myData).thumbRect.right + dist;
-
- } else {
-
- // We have a vertical control
-
- // We need to set the trackRect to take in account of the thumb width.
- // We do this so we don't overwrite part of the arrow when we are drawing.
- trackRect.top += ( MY_THUMB_LENGTH / 2 ) + 1;
- trackRect.bottom -= ( MY_THUMB_LENGTH / 2 ) + 1;
-
- // determine how tall our track rect is and then calculate the distance we move.
- cntl_high = trackRect.bottom - trackRect.top;
- dist = trackRect.top + (((max + value) * cntl_high) / (max - min)) - ( MY_THUMB_LENGTH / 2 );
-
- // we know that the left and right of our thumb rect will be the same as the
- // control's rect (basically). It's actually inset 1 pixel to fit inside the track.
- (*realThumbRect).left = cntlRect.left + 1;
- (*realThumbRect).right = cntlRect.right - 1;
-
- // now set the top and bottom to the correct coordinates for drawing.
- (*realThumbRect).top = (**myData).thumbRect.top + dist;
- (*realThumbRect).bottom = (**myData).thumbRect.bottom + dist;
-
- }
- } else {
-
- // we had a problem getting our data. bummer!
- ReportError( "\pTrying to calculate thumb postion and couldn't access data field." );
-
- }
- }
-
- /******************************************************************************
-
- This procedure will draw the black arrows located in my arrow buttons.
- you pass it a variable that tells which way the arrow should point and a
- rect in which the arrow will be drawn. Fairly straight forward.
-
- 0 = points left
- 1 = points up
- 2 = points right
- 3 = points down
-
- *******************************************************************************/
- void DrawMyArrow( short var, Rect theRect )
- {
- RgnHandle arrow;
- short center;
-
- arrow = NewRgn();
- OpenRgn();
-
- switch( var ) {
-
- case 0: // points left
- center = ( theRect.bottom - theRect.top ) / 2;
- MoveTo( theRect.left + 5, theRect.top + center );
- LineTo( theRect.right - 6, theRect.top + 2 );
- LineTo( theRect.right - 6, theRect.bottom - 4 );
- LineTo( theRect.left + 5, theRect.bottom - center );
- break;
-
- case 1: // points up
- center = ( theRect.right - theRect.left ) / 2;
- MoveTo( theRect.left + 1, theRect.bottom - 6 );
- LineTo( theRect.left + center - 1, theRect.top + 5 );
- LineTo( theRect.right - 3, theRect.bottom - 6 );
- LineTo( theRect.left + 1, theRect.bottom - 6 );
- break;
-
- case 2: // points right
- center = ( theRect.bottom - theRect.top ) / 2;
- MoveTo( theRect.right - 5, theRect.top + center + 1 );
- LineTo( theRect.left + 6, theRect.top + 3 );
- LineTo( theRect.left + 6, theRect.bottom - 4 );
- LineTo( theRect.right - 5, theRect.bottom - center - 1 );
- break;
-
- case 3: // points down
- center = ( theRect.right - theRect.left ) / 2;
- MoveTo( theRect.left + 2, theRect.top + 6 );
- LineTo( theRect.left + center, theRect.bottom - 5 );
- LineTo( theRect.right - 4, theRect.top + 6 );
- LineTo( theRect.left + 2, theRect.top + 6 );
- break;
-
- }
-
- CloseRgn( arrow );
- FillRgn( arrow, &qd.black );
- DisposeRgn( arrow );
- }
-
- /******************************************************************************
-
- Custom Dragging Procedure - not needed if you use default dragging.
- ( when TrackControl is passed a zero for
- the tracking procedure )
-
- Used to move the indicator or thumb.
-
- This procedure will show the user the interaction when they click on the
- thumb part of our control. All we are going to do is drag the thumb's
- rect around using the drag grey rgn routine untill the user let's up on the
- mouse. For kicks and grins we will also draw the control's value above the
- indicator. We also will use the parameters that we set for slop rect and limit rect.
-
- *******************************************************************************/
- void DragMyThumb( ControlHandle theControl, Point mousePnt )
- {
- RgnHandle thumbRgn;
- Rect slopRect, limitRect, realThumbRect, cntlRect;
- long newPoint;
- MyCntlDataHan myData;
- short value, axis;
-
- // set up some variables..
- myData = (MyCntlDataHan)(**theControl).contrlData; // force the data to form to our struct
- cntlRect = (**theControl).contrlRect;
-
- // double check to make sure that in fact we have data to play with
- if( myData != nil ) {
-
- // it worked, hurray.
-
- // let's get the true or real thumb rect ( the one that gets drawn )
- CalcMyThumbPosition( theControl, &realThumbRect );
-
- // this is where we are declaring the parameters for dragging.
- slopRect = limitRect = (**myData).trackRect;
-
- // now let's determine if we are using a horz or vert control
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we have ourselves a horizontal control
-
- // adjust the limitRect to take in account where the user clicked within the thumb
- limitRect.left = (**myData).arrowLT.right + ( mousePnt.h - realThumbRect.left );
- limitRect.right = (**myData).arrowRB.left - ( (realThumbRect.right-1) - mousePnt.h );
-
- // now let's adjust the slopRect slightly, increase it by 20 pixels...
- InsetRect( &slopRect, -20, -20 );
-
- // then extend it's edges about 100 pixels. This normally gives the correct feel.
- slopRect.left -= 100;
- slopRect.right += 100;
-
- // define our axis that we will use to constrain the indicators movement.
- axis = hAxisOnly;
-
- } else {
-
- // we have a vertical control.
-
- // adjust the limitRect to take in account where the user clicked within the thumb
- limitRect.top = (**myData).arrowLT.bottom + ( mousePnt.v - realThumbRect.top );
- limitRect.bottom = (**myData).arrowRB.top - ( (realThumbRect.bottom-1) - mousePnt.v );
-
- // now let's adjust the slopRect slightly, increase it by 20 pixels...
- InsetRect( &slopRect, -20, -20 );
-
- // then extend it's edges about 100 pixels. This normally gives the correct feel.
- slopRect.top -= 100;
- slopRect.bottom += 100;
-
- // define our axis that we will use to constrain the indicators movement.
- axis = vAxisOnly;
-
- }
-
- // we've been asked to only move the indicator
-
- // now do our dragging. first declare a new rgn to copy out thumb rect into.
- // then this gets passed to the DragGrayRgn() procedure. It actually handles the dragging.
- thumbRgn = NewRgn();
- RectRgn( thumbRgn, &realThumbRect );
-
- // This is the actual routine to drag the indicator. For a more detailed explanation
- // look on page 4-96 in IM:Toolbox Essentails or use Think Refrence.
- newPoint = DragGrayRgn( thumbRgn, mousePnt, &limitRect, &slopRect, axis, nil );
-
- // now determine if the thumb did in fact move. if DragGrayRgn() returns a value of
- // 0x80008000 it means that the user realeased the mouse outside the sloprect. HiWord
- // of newPoint is the vertical dist moved where as the LoWord is horz dist moved.
-
- if( newPoint != 0x80008000 ) {
-
- // It was released inside our control. newPoint will contain the horizontal and vertical
- // ditance moved.
-
- mousePnt.h = LoWord( newPoint );
- mousePnt.v = HiWord( newPoint );
- ConvertPtToVal( theControl, mousePnt, &value );
- SetCtlValue( theControl, value );
- DrawMyThumb( theControl, 1 );
- DrawValueInThumb( theControl, value );
-
- } else {
-
- // it was released outside the slopRect. Do nothing
- ReportError( "\pYou released the mouse outside the slop Rect." );
-
- }
-
- DisposeRgn( thumbRgn );
-
- } else {
-
- // it didn't work
- ReportError( "\pCouldn't retrieve control data while dragging the control's thumb." );
-
- }
- }
-
- /******************************************************************************
-
-
-
- Custom Dragging Procedure - not needed if you use default dragging.
- ( when TrackControl is passed a zero for
- the tracking procedure )
-
- Used to move the entire control.
-
- This procedure is only used when the user is given the ability to move
- the entire control. I really haven't thought of any reason to do this, but
- if it's something that is implicated in your code then here it is.
-
- limitRect - will most likely be the control's ownern's content region.
- slopRect - will be whatever value you think should be used. for tutorial
- purposes I'll use the window's content region inset -20
- axis - I'll assume that you would want to give them complete freedom.
- No constraint.
-
- *******************************************************************************/
- void DragMyControl( ControlHandle theControl, Point mousePnt )
- {
- Rect slopRect, limitRect, cntlRect;
- short axis;
- WindowPtr cntlWindow;
-
- // set up some variables..
- cntlRect = (**theControl).contrlRect;
- cntlWindow = (**theControl).contrlOwner;
-
- // this is where we are declaring the parameters for dragging.
- slopRect = limitRect = (*cntlWindow).portRect;
-
- // now let's determine if we are using a horz or vert control
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we have ourselves a horizontal control
-
- // adjust the limitRect to take in account where the user clicked within the control
- limitRect.left = cntlRect.left + mousePnt.h;
- limitRect.right = cntlRect.right - mousePnt.h;
-
- // now let's adjust the slopRect slightly, increase it by 20 pixels...
- InsetRect( &slopRect, -20, -20 );
-
- // define our axis that we will use to constrain the indicators movement.
- axis = noConstraint;
-
- } else {
-
- // we have a vertical control.
-
- // adjust the limitRect to take in account where the user clicked whithin the control
- limitRect.top = cntlRect.top + mousePnt.v;
- limitRect.bottom = cntlRect.bottom - mousePnt.v;
-
- // now let's adjust the slopRect slightly, increase it by 20 pixels...
- InsetRect( &slopRect, -20, -20 );
-
- // define our axis that we will use to constrain the indicators movement.
- axis = noConstraint;
-
- }
-
- // This is the actual routine used to drag the entire control for a more detailed
- // exlpaination look on page 5-99 IM:Toolbox Essentails or use Think Refrence.
- DragControl( theControl, mousePnt, &limitRect, &slopRect, axis );
-
- }
- /******************************************************************************
-
- All this procedure does is draw the thumb depending on the current control
- value. Fairly straight forward procedure. It will get called after the
- user drags the thumb and if the control recieves a draw entire control msg.
-
- I added a simply variable to tell my drawing procedure if I'm drawing for
- custom dragging or default dragging. Since I didn't do anything to wild
- for my dragging I'm using this instead. If the value is 0 then it just
- draws the thumb normally. If anything else it draws it with the value in
- the middle.
-
- *******************************************************************************/
- void DrawMyThumb( ControlHandle theControl, Boolean var )
- {
- Rect realThumbRect, trackRect;
- MyCntlDataHan myData;
-
- // set up some variables..
- myData = (MyCntlDataHan)(**theControl).contrlData; // force the data to form to our struct
-
- // double check to make sure that in fact we have data to play with
- if( myData != nil ) {
-
- // it worked we have data to play with
-
- // first draw the track ( to erase any old thumb positions )
- trackRect = (**myData).trackRect;
-
- SetForeColor( GREY_A );
- PaintRect( &trackRect );
-
- //--- add hilites and shadows
- HiliteAndShadow( GREY_C, WHITE_COLOR, 0, trackRect );
- FrameRect( &trackRect );
-
- //--- since we now know how large our thumb is, where should we draw it?
- //--- the position is stored in the control's value field.
- CalcMyThumbPosition( theControl, &realThumbRect );
- SetForeColor( GREY_B );
- PaintRect( &realThumbRect );
-
- //--- add hilites and shadows
- HiliteAndShadow( WHITE_COLOR, GREY_E, 0, realThumbRect );
- FrameRect( &realThumbRect );
-
- if( var != 0 ) {
-
- // draw the text in the middle
- DrawValueInThumb( theControl, (**theControl).contrlValue );
-
- }
-
- } else {
-
- // we couldn't obtain the data for some reason.
- ReportError( "\pCouldn't access control data while attempting to draw the thumb." );
-
- }
- }
-
- /******************************************************************************
-
- All we do here is calculate our thumb rect, convert to a region and copy it
- into param (which is asking for a region handle) This is done so that the
- user can drag our thumb.
-
- *******************************************************************************/
- void CalcMyThumbRgn( ControlHandle theControl, RgnHandle *param )
- {
- Rect realThumbRect;
-
- // first let's find the real thumb rect
- CalcMyThumbPosition( theControl, &realThumbRect );
-
- // now just convert it into a rgn (using the pointer to param )
- RectRgn( *param, &realThumbRect );
- }
-
- /******************************************************************************
-
- Our control was sent a 'posCntl' in the message parameter. param contains the
- horizontal and vertical offset to move your indicator from it's current
- position. ( vert = HiWord, horz = LoWord ).
-
- We will calculate the new setting and then redraw the control and update
- it's control value.
-
- This one through me for a loop. I wasn't recieving a posCntl for the life of
- me. I figured out that I wasn't setting the param correctly in FillCntlParameters().
- I wasn't forcing the data within param to my struct 'CntlParms' correctly. I
- was forgetting to typeCast the param when sending it to my function. It's
- the little things like that that will drive you crazy.
-
- *******************************************************************************/
- void PositionMyCntl( ControlHandle theControl, Point mousePnt )
- {
- short value;
-
- // All we have to do is calculate the new thumb value and then
- // use CalcMyThumbPosition() to figure out the new location
- // of the thumb. TrackControl() will handle the draggin if things
- // are set up correctly in FillCntlParameters().
-
- // First convert the point given to us into a new value
- ConvertPtToVal( theControl, mousePnt, &value );
-
- // set the control's value to this new value
- SetCtlValue( theControl, value );
-
- // Now just redraw the indicator or thumb.
- DrawMyThumb( theControl, 0 );
- }
-
- /******************************************************************************
-
- This procedure will take a point that is within the track Rectangle
- and convert it to a value.
-
- *******************************************************************************/
- void ConvertPtToVal( ControlHandle theControl, Point newPoint, short *value )
- {
- Rect trackRect, cntlRect, realThumbRect;
- short currThumbCenter, newThumbCenter, trackWidth;
- long min, max, newValue;
- MyCntlDataHan myData;
-
- // extract the control data and form to our struct.
- myData = (MyCntlDataHan)(**theControl).contrlData;
-
- // double check to make sure that in fact we have data to play with
- if( myData != nil ) {
-
- // set up some initial variables
- trackRect = (**myData).trackRect;
- cntlRect = (**theControl).contrlRect;
- min = (**theControl).contrlMin;
- max = (**theControl).contrlMax;
-
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // it's a horizontal control
-
- // take in account the thumb length for the edges of the track. I added one
- // because it had a tendancy to round down and not set my complete value.
- trackRect.right -= ( MY_THUMB_LENGTH / 2 ) + 1;
- trackRect.left += ( MY_THUMB_LENGTH / 2 ) + 1;
-
- // we need to obtain the center of the current thumb position
- CalcMyThumbPosition( theControl, &realThumbRect );
- currThumbCenter = realThumbRect.left + (( realThumbRect.right - realThumbRect.left ) / 2 );
-
- // determine the thumbs new center with the given offset.
- newThumbCenter = currThumbCenter + newPoint.h;
-
- // make sure the point isn't outside the track now that we made adjustments.
- if( newThumbCenter < trackRect.left ) {
-
- newThumbCenter = trackRect.left;
-
- } else {
-
- if( newThumbCenter > trackRect.right ) {
-
- newThumbCenter = trackRect.right;
-
- }
- }
-
- // find the width of our track rect
- trackWidth = trackRect.right - trackRect.left;
-
- // calculate our new value.
- newValue = min + ( ( max - min ) * ( newThumbCenter - trackRect.left ) ) / trackWidth;
-
- } else {
-
- // it's a vertical control
-
- // take in account the thumb length for the edges of the track.
- trackRect.bottom -= ( MY_THUMB_LENGTH / 2 ) + 1;
- trackRect.top += ( MY_THUMB_LENGTH / 2 ) + 1;
-
- // we need to obtain the center of the current thumb position
- CalcMyThumbPosition( theControl, &realThumbRect );
- currThumbCenter = realThumbRect.top + (( realThumbRect.bottom - realThumbRect.top ) / 2 );
-
- // determine the thumbs new center with the given offset.
- newThumbCenter = currThumbCenter + newPoint.v;
-
- // make sure the point isn't outside the track now that we made adjustments.
- if( newThumbCenter < trackRect.top ) {
-
- newPoint.v = trackRect.top;
-
- } else {
-
- if( newThumbCenter > trackRect.bottom ) {
-
- newPoint.v = trackRect.bottom;
-
- }
- }
-
- // find the height of our track rect
- trackWidth = trackRect.bottom - trackRect.top;
-
- // calculate our new value.
- newValue = min + ( ( max - min ) * ( newThumbCenter - trackRect.top ) ) / trackWidth;
-
- }
-
- *value = newValue;
-
- } else {
-
- // We had problems extracting the data from the control's data field
- ReportError( "\pCouldn't access the control's data while converting a point to a value." );
-
- }
- }
-
- /******************************************************************************
-
- Custom Dragging Procedure - not needed if you use default dragging.
- ( when TrackControl is passed a zero for
- the tracking procedure )
-
- Used to draw the controls value within the thumb.
-
- This is just to show an example of how you could use custom dragging. This
- is anything to fancy. Will just take the contol's value. Make sure it will
- fit within our thumb and draw it in its center. For the sake of simplicity
- we will not do this for a vertical control.
-
- In reality you could use this for default draggin also, but I justed wanted
- to show you something. I'm using a standard drag procedure for my custom
- dragging so you really don't notice any big difference. This at least shows
- some difference.
-
- *******************************************************************************/
- void DrawValueInThumb( ControlHandle theControl, long value )
- {
- Rect realThumbRect, cntlRect;
- Str15 numString, errString = "\p???"; // will never be greater than 4 digits with our values.
- short center, strWidth; // used to draw our text.
- GrafPtr thePort; // used to get font info
- short txFont, txSize, txFace, txMode; // to store current font info.
- RGBColor theColor;
-
- // first it helps to set the cntlRect
- cntlRect = (**theControl).contrlRect;
-
- if( cntlRect.right - cntlRect.left > cntlRect.bottom - cntlRect.top ) {
-
- // we have a horizontal control
-
- // we do this to find out current font settings.
- GetPort( &thePort );
-
- // Set up some variables and also find & change the current font information
- NumToString( value, numString );
- cntlRect = (**theControl).contrlRect;
- txFont = (*thePort).txFont;
- txSize = (*thePort).txSize;
- txFace = (*thePort).txFace;
- txMode = (*thePort).txMode;
- GetBackColor( &theColor );
- TextFont( 9 );
- TextSize( 9 );
- TextFace( 0 );
- TextMode( 0 ); // for this to work and erase the background we need to
- // be sure to set the background color to the thumb color.
-
- SetBackColor( GREY_B ); // this is the thumbs color
-
- // find the real thumb position
- CalcMyThumbPosition( theControl, &realThumbRect );
-
- // let's double check to make sure our value is bigger than four digits
- if( numString[0] > 0x04 ) {
-
- // we can't have that happen
- BlockMove( &errString[0], &numString[0], 4 );
-
- }
-
- center = realThumbRect.left + (( realThumbRect.right - realThumbRect.left ) / 2 );
- strWidth = StringWidth( numString );
-
- MoveTo( center - ( strWidth / 2 ), realThumbRect.bottom - 4 );
- DrawString( numString );
-
- // redraw hilites and shadows on the thumb because we overWrite them slightly
- HiliteAndShadow( WHITE_COLOR, GREY_E, 0, realThumbRect );
- FrameRect( & realThumbRect );
-
- // be nice and return everything back to the way they were.
- TextFont( txFont );
- TextSize( txSize );
- TextFace( txFace );
- TextMode( txMode );
- RGBBackColor( &theColor );
-
- } else {
-
- // we have a vertical control so let's not bother
-
- }
- }
-
-
-
-
-
-
-
-
-